<template>
  <div class="app-container">
    <div>
      <el-cascader aria-label="公告类别" style="width: 300px;" size="small" class="filter-item" placeholder="公告类别"
        @change="refreshNews" v-model="newsViewModel.TypeID" :options="newsTypeList"
        :props="{ checkStrictly: true, emitPath: false,expandTrigger: 'hover' }" filterable clearable></el-cascader>
      <el-input v-model="newsViewModel.Title" size="small" placeholder="标题" style="width: 200px;" class="filter-item"
        @keyup.enter.native="queryNews" />
      <el-input v-model="newsViewModel.SubTitle" size="small" placeholder="副标题" style="width: 200px;"
        class="filter-item" @keyup.enter.native="queryNews" />
      <el-select v-model="newsViewModel.States" size="small" placeholder="请选择">
        <el-option v-for="item in StatesList" :key="item.key" :label="item.title" :value="item.key"></el-option>
      </el-select>
      <el-button type="primary" size="small" @click="queryNews" icon="el-icon-search">查询</el-button>
      <el-button type="primary" size="small" @click="handleAdd" icon="el-icon-plus">新增</el-button>
      <el-button type="primary" size="small" @click="refreshNews" icon="el-icon-refresh">刷新</el-button>
    </div>
    <el-table :data="newsList" v-loading="loading" :header-cell-style="{background:'#eef1f6',color:'#606266'}"
      style="width: 100%;margin-top:30px;" border @sort-change="sortChange">
      <el-table-column label="标题" prop="Title">
        <template slot-scope="scope">{{ scope.row.Title }}</template>
      </el-table-column>
      <el-table-column label="副标题" prop="SubTitle">
        <template slot-scope="scope">{{ scope.row.SubTitle }}</template>
      </el-table-column>
      <!-- <el-table-column label="发布署名" prop="Signature">
        <template slot-scope="scope">{{ scope.row.Signature }}</template>
      </el-table-column> -->
      <el-table-column label="发布状态" prop="StateStr">
        <template slot-scope="scope">{{ scope.row.StateStr }}</template>
      </el-table-column>
      <el-table-column label="发布时间" sortable="ReleaseTime" prop="ReleaseTime">
        <template slot-scope="scope">{{ scope.row.ReleaseTime }}</template>
      </el-table-column>
      <el-table-column align="center" label="操作">
        <template slot-scope="scope">
          <el-button type="text" v-if="scope.row.States==0||scope.row.States==2" size="mini"
            @click="handlePublish(scope,1)" icon="el-icon-top">上架</el-button>
          <el-button type="text" v-else size="mini" @click="handlePublish(scope,2)" icon="el-icon-bottom">下架</el-button>
          <el-button type="text" size="small" @click="handleEdit(scope)" icon="el-icon-edit">编辑</el-button>
          <el-button type="text" v-if="scope.row.IsStick>scope.row.CreateTime" size="mini"
            @click="CancelPublish(scope,0)" icon="el-icon-bottom">取消置顶</el-button>
          <el-button type="text" v-else size="mini" @click="CancelPublish(scope,1)" icon="el-icon-top">置顶</el-button>
          <el-button type="text" size="small" @click="handleDelete(scope)" icon="el-icon-delete">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件：https://element.eleme.cn/#/zh-CN/component/pagination -->
    <div class="block" style="float:right;margin-top:15px;" v-if="newsViewModel.total>0">
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
        :current-page="newsViewModel.page" :page-sizes="[10, 20, 30, 40,100]" :page-size="newsViewModel.pageSize"
        @prev-click="lastPage" @next-click="nextPage" background layout="total, sizes, prev, pager, next, jumper"
        :total="newsViewModel.total"></el-pagination>
    </div>

    <el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'编辑':'新增'" @close="closeDialog" width="60%"
      top="2vh" :close-on-click-modal="false">
      <el-form :model="model" ref="model" :rules="rules" label-width="80px" label-position="right" style="width: 90%;">

        <el-row>
          <el-col :span="24">
            <el-form-item label="标题" prop="Title">
              <el-input v-model="model.Title" placeholder="标题" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="副标题" prop="SubTitle">
              <el-input v-model="model.SubTitle" placeholder="副标题" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="新闻封面">
              <el-radio-group v-model="model.IsSingle">
                <el-radio :label="true">单封面</el-radio>
                <el-radio :label="false">3封面</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>

        <el-row>
          <el-col :span="8">
            <el-form-item label="封面" prop="SourceUrl">
              <el-upload class="avatar-uploader" id="uploadimginput" :action="actionUrl" :show-file-list="false"
                :on-success="handleAvatarSuccess1" :before-upload="beforeAvatarUpload">
                <img v-if="this.image1" :src="this.image1" class="avatar" />
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item prop="SourceUrl1" v-if="!model.IsSingle">
              <el-upload class="avatar-uploader" id="uploadimginput" :action="actionUrl" :show-file-list="false"
                :on-success="handleAvatarSuccess2" :before-upload="beforeAvatarUpload">
                <img v-if="this.image2" :src="this.image2" class="avatar" />
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
          </el-col>
          <el-col :span="8">
            <el-form-item prop="SourceUrl2" v-if="!model.IsSingle">
              <el-upload class="avatar-uploader" id="uploadimginput" :action="actionUrl" :show-file-list="false"
                :on-success="handleAvatarSuccess3" :before-upload="beforeAvatarUpload">
                <img v-if="this.image3" :src="this.image3" class="avatar" />
                <i v-else class="el-icon-plus avatar-uploader-icon"></i>
              </el-upload>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="公告类别" prop="NewsTypeIdList">
              <el-cascader aria-label="公告类别" style="width:100%" placeholder="请选择公告类别" v-model="model.NewsTypeIdList"
                :options="newsTypeList"
                :props="{ checkStrictly: true, multiple: true, emitPath: false,expandTrigger: 'hover' }" filterable
                clearable></el-cascader>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- <el-row>
          <el-col :span="12">
            <el-form-item label="发布署名" prop="Signature">
              <el-input v-model="model.Signature" placeholder="发布署名" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="序号" prop="Sort">
              <el-input-number v-model="model.Sort" :min="0" label="序号" style="width: 100%"></el-input-number>
            </el-form-item>
          </el-col>
        </el-row> -->

        <el-row>
          <el-col :span="24">
            <el-form-item label="内容" prop="Text">
              <!-- <tinymce v-model="model.Text" :height="200" /> -->
              <div class="editor" ref="editor"></div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div style="text-align:right;">
        <el-button type="danger" @click="dialogVisible=false">取消</el-button>
        <el-button type="primary" @click="confirmModel">提交</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<style>
  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .avatar-uploader .el-upload:hover {
    border-color: #409eff;
  }

  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }

  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }

  .v-modal {
    z-index: 2000 !important;
  }
</style>

<script>
  import {
    getNewsList,
    addNews,
    updateNews,
    deleteNews,
    getAllNewsTypeList,
    publishModel,
    TopModel
  } from "@/api/news";
  import { deepClone } from "@/utils";
  import Tinymce from "@/components/Tinymce";
  import { GetDictionaryByPCode } from "@/api/dictionary";
  import wangeditor from "wangeditor"

  const defaultModel = {
    Id: "",
    Title: "",
    SubTitle: "",
    IsSingle: true,
    Code: "publish",
    SourceUrl: "",
    Text: "",
    Signature: "",
    ReleaseTime: "",
    ReadCount: "",
    IsStick: "",
    States: "",
    StateStr: "",
    Sort: "",
    Creater: "",
    CreateTime: "",
    Modify: "",
    ModifyTime: "",
    NewsTypeIdList: [],
    SourceURLList: []
  };
  export default {
    components: { Tinymce },
    data() {
      var validatePass2 = (rule, value, callback) => {
        if (value === "") {
          callback(new Error("请确认密码"));
        } else if (value !== this.model.Password) {
          callback(new Error("两次输入密码不一致!"));
        } else {
          callback();
        }
      };
      return {
        newsViewModel: {
          page: 1,
          pageSize: 10,
          total: 0,
          Title: "",
          Code: "publish",
          SubTitle: "",
          TypeID: "",
          States: "-1",
          OrderBy: "IsStick DESC,CreateTime", //排序字段
          IsAsc: true, //是否升序
          NewsTypeIdList: [],
          SourceURLList: []
        },
        image1: "",
        image2: "",
        image3: "",
        loading:false,
        dialogVisible: false,
        dialogType: "",
        model: Object.assign({}, defaultModel),
        newsList: [],
        newsTypeList: [],
        apiPre: process.env.VUE_APP_BASE_API,
        actionUrl: "",
        StatesList: [
          { key: "-1", title: "全部" },
          { key: "0", title: "未发布" },
          { key: "1", title: "已发布" },
          { key: "2", title: "已下架" }
        ],
        rules: {
          Title: [
            { required: true, message: "请输入标题", trigger: "blur" },
            {
              min: 1,
              max: 50,
              message: "长度在 1 到 50 个字符",
              trigger: "blur"
            }
          ],
          SourceUrl: [
            { required: true, message: "请选封面图片", trigger: "blur" }
          ],
          NewsTypeIdList: [
            { required: true, message: "请选择信息分类", trigger: "blur" }
          ],
          ReleaseTime: [
            { required: true, message: "请选择发布时间", trigger: "blur" }
          ]
        }
      };
    },
    computed: {
      // 计算属性，只要相关联的值没有改变，直接返回，不再进行计算，与方法区别，缓存
    },
    created() {
      // 实例创建完成后执行的代码
      this.GetDictionaryByPCode("NewsType");
      this.getNewsList(this.newsViewModel);
      this.actionUrl = this.apiPre + "/Upload/UploadAttachment";
      // this.getAllNewsTypeList()
    },
    methods: {
      createEditor(content) {

        if (this.feditor) {
          if (content) {
            this.feditor.txt.html(content);
          }
          else {
            this.feditor.txt.html('');
          }
          return false
        }

        var editor = new wangeditor(this.$refs.editor);
        editor.customConfig.menus = [
          "head", // 标题
          "bold", // 粗体
          "fontSize", // 字号
          "fontName", // 字体
          "italic", // 斜体
          "underline", // 下划线
          "strikeThrough", // 删除线
          "foreColor", // 文字颜色
          "backColor", // 背景颜色
          "link", // 插入链接
          "list", // 列表
          "justify", // 对齐方式
          "quote", // 引用
          "image", // 插入图片
          'video',  // 插入视频
          "table", // 表格
          "undo", // 撤销
          "redo" // 重复
        ];
        editor.customConfig.zIndex = 2000;
        editor.customConfig.uploadImgServer =
          process.env.VUE_APP_BASE_API + "/Upload/UploadAttachment";
        editor.customConfig.onchange = html => {
          this.model.Text = html;
        };
        // 将图片大小限制为 3M
        editor.customConfig.uploadImgMaxSize = 5 * 1024 * 1024;
        editor.customConfig.uploadImgHooks = {
          success: function (xhr, editor, result) {
            // 图片上传并返回结果，图片插入成功之后触发
            // xhr 是 XMLHttpRequst 对象，editor 是编辑器对象，result 是服务器端返回的结果
          },
          fail: function (xhr, editor, result) {
            // 图片上传并返回结果，但图片插入错误时触发
            // xhr 是 XMLHttpRequst 对象，editor 是编辑器对象，result 是服务器端返回的结果
            this.$notify({
              title: "错误",
              type: "warning",
              message: "上传图片失败!"
            });
          },
          error: function (xhr, editor) {
            // 图片上传出错时触发
            // xhr 是 XMLHttpRequst 对象，editor 是编辑器对象
            this.$notify({
              title: "错误",
              type: "warning",
              message: "上传图片错误!"
            });
          },
          timeout: function (xhr, editor) {
            // 图片上传超时时触发
            // xhr 是 XMLHttpRequst 对象，editor 是编辑器对象
            this.$notify({
              title: "错误",
              type: "warning",
              message: "上传图片超时!"
            });
          },
          // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式，可使用该配置
          // （但是，服务器端返回的必须是一个 JSON 格式字符串！！！否则会报错）
          customInsert: function (insertImg, result, editor) {
            // 图片上传并返回结果，自定义插入图片的事件（而不是编辑器自动插入图片！！！）
            // insertImg 是插入图片的函数，editor 是编辑器对象，result 是服务器端返回的结果
            // 举例：假如上传图片成功后，服务器端返回的是 {url:'....'} 这种格式，即可这样插入图片：
            // window.console.log(result);
            var url = result.data.DownloadUrl;
            insertImg(url);
          }
        };
        editor.create();
        if (content) {
          editor.txt.html(content);
        }
        else {
          editor.txt.html('');
        }
        this.feditor = editor;
      },
      async GetDictionaryByPCode(ams) {
        const res = await GetDictionaryByPCode(ams);
        this.newsTypeList = res.data;
      },
      async getNewsList(newsViewModel) {
        this.loading = true
        const res = await getNewsList(newsViewModel);
        if (res.data) {
          this.newsViewModel.total = res.data.TotalCount;
        }
        this.newsList = res.data.NewsItems;
        this.loading = false
      },
      async getAllNewsTypeList() {
        const res = await getAllNewsTypeList();
        this.newsTypeList = res.data;
      },
      closeDialog() { },
      queryNews() {
        this.newsViewModel.page = 1;
        this.getNewsList(this.newsViewModel);
      },
      refreshNews() {
        this.newsViewModel.Title = "";
        this.newsViewModel.SubTitle = "";
        this.newsViewModel.States = "-1";
        this.newsViewModel.page = 1;
        this.getNewsList(this.newsViewModel);
      },
      sortChange(data) {
        const { prop, order } = data;
        this.newsViewModel.OrderBy = prop;
        if (prop == null || prop == "") this.newsViewModel.OrderBy = "UserID";
        if (order === "ascending") {
          this.newsViewModel.IsAsc = true;
        } else {
          this.newsViewModel.IsAsc = false;
        }
        this.queryNews();
      },
      lastPage(val) {
        this.newsViewModel.page = val;
      },
      nextPage(val) {
        this.newsViewModel.page = val;
      },
      handleChange(value) {
        console.log(value);
      },
      handleSizeChange(val) {
        this.newsViewModel.pageSize = val;
        this.getNewsList(this.newsViewModel);
      },
      handleCurrentChange(val) {
        this.newsViewModel.page = val;
        this.getNewsList(this.newsViewModel);
      },
      handlePublish(scope, status) {
        var str = "下架";
        if (status == 1) str = "上架";
        this.$confirm("确认" + str + scope.row.Title + "?", "提示", {
          confirmButtonText: "确认",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(async () => {
            await publishModel(scope.row.Id, status);
            this.$notify({
              title: "成功",
              type: "success",
              message: "操作成功!"
            });
            this.queryNews();
          })
          .catch(err => {
            console.error(err);
          });
      },
      CancelPublish(scope, status) {
        var str = "置顶";
        if (status == 0) str = "取消置顶";
        this.$confirm("确认" + str + scope.row.Title + "?", "提示", {
          confirmButtonText: "确认",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(async () => {
            await TopModel(scope.row.Id, status);
            this.$notify({
              title: "成功",
              type: "success",
              message: "操作成功!"
            });
            this.queryNews();
          })
          .catch(err => {
            console.error(err);
          });
      },

      handleAdd() {
        this.model = deepClone(defaultModel);
        this.$nextTick(() => {
          this.createEditor('')
          this.$refs["model"].clearValidate(); //清空上次的错误验证提示
        });
        this.Text = "";
        this.dialogType = "new";
        this.dialogVisible = true;
        this.image1 = "";
        this.image2 = "";
        this.image3 = "";
      },
      handleEdit(scope) {
        this.GetDictionaryByPCode("NewsType");
        this.dialogType = "edit";
        this.dialogVisible = true;
        this.model = deepClone(scope.row);
        this.$nextTick(() => {
          this.createEditor(this.model.Text)
          this.$refs["model"].clearValidate(); //清空上次的错误验证提示
        });
        if ((this.model.SourceURLList.length = 3)) {
          this.image1 = this.model.SourceURLList[0];
          this.image2 = this.model.SourceURLList[1];
          this.image3 = this.model.SourceURLList[2];
        } else if ((this.model.SourceURLList.length = 2)) {
          this.image1 = this.model.SourceURLList[0];
          this.image2 = this.model.SourceURLList[1];
        } else if ((this.model.SourceURLList.length = 1)) {
          this.image1 = this.model.SourceURLList[0];
        }
      },
      async confirmModel() {
        //如果把验证失败弹出提示代码放在validate里面则不会弹出错误提示，直接走下面的更新操作代码
        var v;
        this.$refs["model"].validate(valid => {
          v = valid;
        });
        if (!v) {
          return false;
        }
        const isEdit = this.dialogType === "edit";
        this.model.SourceURLList.length = 0;
        this.model.SourceURLList.unshift(this.image3);
        this.model.SourceURLList.unshift(this.image2);
        this.model.SourceURLList.unshift(this.image1);
        if (isEdit) {
          await updateNews(this.model);
        } else {
          await addNews(this.model);
          this.newsViewModel.page = 1;
        }
        this.getNewsList(this.newsViewModel);
        this.model = deepClone(defaultModel);
        this.dialogVisible = false;
        this.$notify({
          title: "成功",
          type: "success",
          message: "操作成功!"
        });
      },
      handleDelete({ $index, row }) {
        this.$confirm("确认删除?", "提示", {
          confirmButtonText: "确认",
          cancelButtonText: "取消",
          type: "warning"
        })
          .then(async () => {
            await deleteNews(row.Id);
            this.$notify({
              title: "成功",
              type: "success",
              message: "操作成功!"
            });
            this.getNewsList(this.newsViewModel);
          })
          .catch(err => {
            console.error(err);
          });
      },
      handleAvatarSuccess1(res, file) {
        //图片上传成功响应方法
        this.model.SourceUrl = res.data.DownloadUrl;
        this.image1 = res.data.DownloadUrl;
      },
      handleAvatarSuccess2(res, file) {
        //图片上传成功响应方法
        this.image2 = res.data.DownloadUrl;
      },
      handleAvatarSuccess3(res, file) {
        //图片上传成功响应方法
        this.image3 = res.data.DownloadUrl;
      },
      beforeAvatarUpload(file) {
        const isImg = file.type === "image/jpeg" || file.type === "image/png";
        const isLt2M = file.size / 1024 / 1024 < 5;

        if (!isImg) {
          this.$notify({
            title: "失败",
            message: "上传封面图片只能是 JPG/JPEG/PNG 格式!",
            type: "error",
            duration: 3000
          });
          return false;
        }
        if (!isLt2M) {
          this.$notify({
            title: "失败",
            message: "上传封面图片大小不能超过 5MB!",
            type: "error",
            duration: 3000
          });
          return false;
        }
        return true;
      }
    }
  };
</script>